#ifdef KITSCHY_DEBUG_MEMORY 
#include "debug_memorymanager.h"
#endif

#ifdef WIN32
#include "windows.h"
#endif

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include "BList.h"
#include "BVector.h"
#include "geometrics.h"
#include "quaternion.h"

#include "symbol.h"
#include "sort.h"
#include "ontology.h"
#include "featureterm.h"
#include "FTKBase.h"

#include "myglutaux.h"
#include "FTGLPolygonFont.h"
#include "AWLocalViewport.h"
#include "AWLVP_NOOSOntology.h"

#include "AWEntity.h"
#include "AWMessage.h"
#include "AWBody.h"
#include "AWMsgMoveBody.h"
#include "AWNOOSCBBody.h"

#include "CaseBaseUtils.h"

#include "loader.h"


extern int SCREEN_DX,SCREEN_DY;

AW_LVP_NOOSOntology::AW_LVP_NOOSOntology(int x,int y,int dx,int dy,Ontology *o,FTKBase *cb) : AW_LocalViewport(x,y,dx,dy)
{
	m_ontology=o;
	m_casebase=cb;
	m_font=0;
	m_ontology_start=0;
	m_selected_sort=0;
} /* AW_LVP_NOOSOntology::AW_LVP_NOOSOntology */ 


AW_LVP_NOOSOntology::~AW_LVP_NOOSOntology()
{
	m_ontology=0;
	m_casebase=0;

#ifndef KITSCHY_DEBUG_MEMORY 
	// I don't know why, but the memory_manager complains about this free:
	if (m_font!=0) delete m_font;
#endif
} /* AW_LVP_NOOSOntology::~AW_LVP_NOOSOntology */ 


Sort *AW_LVP_NOOSOntology::get_selected_sort(void)
{
	return m_selected_sort;
} /* AW_LVP_NOOSOntology::get_selected_sort */ 



void AW_LVP_NOOSOntology::draw_internal(void)
{
	float f=1.0F;
	int vpx=0,vpy=0,vpw=800,vph=600;

	if (m_font==0) {
		FILE *fp=fopen("arial.ttf","r");
		if (fp!=0) {
			fclose(fp);
			m_font=new FTGLPolygonFont("arial.ttf");
			m_font->FaceSize(2);
			m_font->Depth(0.2F);
		} else {
			return;
		} /* if */ 
	} /* if */ 

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	{
		int tmp[4];
		glGetIntegerv(GL_VIEWPORT,tmp);
		vpx=tmp[0];
		vpy=tmp[1];
		vpw=tmp[2];
		vph=tmp[3];
		f=float(vpw)/float(vph);
	}


	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	{
		float x=0,y=0;
		List<Sort> sorts;
		List<int> tabs;
		Sort *s;
		int *i;
		int name;
		int num=0;

		glPushMatrix();
		glTranslatef(-0.95,0.85,0);

		glScalef(0.2F/f,0.2F,0.2F);

		sorts.Add(m_ontology->get_sort("any"));
		tabs.Add(new int(0));

		while(!sorts.EmptyP()) {
			s=sorts.ExtractIni();
			i=tabs.ExtractIni();

			x=(*i)*0.6F;
			
			if (num>=m_ontology_start) {
				/* Draw current sort: */ 
				name=10+m_ontology->get_sort_num(s);
				glPushName(name);
				glPushMatrix();
				glTranslatef(x,-y,0);
				{
					float llx,lly,llz,urx,ury,urz;
					char tmp[256];
					int n_ft=0;

					{
						List<FeatureTerm> *l;
						l=m_casebase->LocalSearchFT(s);
						if (l!=0) n_ft=l->Length();
						while(!l->EmptyP()) l->ExtractIni();
						delete l;
					}

					if (n_ft!=0) sprintf(tmp,"%s (%i)",s->get(),n_ft);
							else sprintf(tmp,"%s",s->get());

					m_font->BBox( tmp, llx, lly, llz, urx, ury, urz);		
					glPushMatrix();
					glScalef(0.2F,0.2F,0.2F);
					glTranslatef((urx-llx)/2+1,-((ury-lly)/2+1),0);
					if (is_a_case(s)) {
						glColor3f(1,0,0);
						glutSolidBox((urx-llx)/2+1.4F,1.2F,0.03F);
					} /* if */ 
					if (m_selected_sort==s) {
						glColor3f(1.0F,0.3F,0.15F);
					} else {
						glColor3f(0.15F,0.5F,0.8F);
					} /* if */ 
					glutSolidBox((urx-llx)/2+1,1,0.05F);
					glTranslatef(-((urx-llx)/2+1),0,0);
					glTranslatef(0.5,-0.5F,-0.1F);
					glColor3f(1,1,1);
					glNormal3f(0,0,-1);
					m_font->Render(tmp);
					glPopMatrix();
				}
				glPopMatrix();
				glPopName();
				y+=0.6F;
			} /* if */ 
			num++;

			/* Add subsorts to the list: */ 
			{
				List<Sort> *l;
				Sort *s1;

				l=s->getSubSorts();
				l->Rewind();
				while(l->Iterate(s1)) {
					sorts.Insert(s1);
					tabs.Insert(new int((*i)+1));
				} /* while */ 
				delete l;
			}

			delete i;
		} /* while */ 

		glPopMatrix();

		// Draw the up/down buttons:
		glPushName(1);
		glPushMatrix();
		glTranslatef(0,0.95,0);
		glColor3f(0.75F,0.75F,1);
		glutSolidBox(1,0.05,0.01F);
		glColor3f(1,1,1);
		glBegin(GL_TRIANGLES);
		glVertex3f(-0.2,-0.04,-0.05);
		glVertex3f(0.2,-0.04,-0.05);
		glVertex3f(0.0,0.04,-0.05);
		glEnd();
		glPopMatrix();
		glPopName();

		glPushName(2);
		glPushMatrix();
		glTranslatef(0,-0.95,0);
		glColor3f(0.75F,0.75F,1);
		glutSolidBox(1,0.05,0.01F);
		glColor3f(1,1,1);
		glBegin(GL_TRIANGLES);
		glVertex3f(0.2,0.04,-0.05);
		glVertex3f(-0.2,0.04,-0.05);
		glVertex3f(0.0,-0.04,-0.05);
		glEnd();
		glPopMatrix();
		glPopName();
	}

	glPopMatrix();

} /* AW_LVP_NOOSOntology::draw_internal */ 


bool AW_LVP_NOOSOntology::MouseClick_internal(int selected)
{
	switch(selected) {
	case 1: /* up */ 
			if (m_ontology_start>0) m_ontology_start-=5;
			if (m_ontology_start<0) m_ontology_start=0;
			break;
	case 2: /* down */ 
			m_ontology_start+=5;
			break;
	default:/* sorts */ 
			if (selected>=10) {
				m_selected_sort=m_ontology->get_sort_num(selected-10);
			} else {
				m_selected_sort=0;
			} /* if */ 
			break;
	} /* switch */ 
	
	return true;
} /* AW_LVP_NOOSOntology::MouseClick */ 